﻿using Blm.PgsqlDriver.Common;
using Blm.PgsqlDriver.Helpers;
using Blm.RabbitMQ.Extensions;
using Blm.RabbitMQ.Models;
using Meta.RabbitMQ.Consumer;
using Meta.RabbitMQ.Generic;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Npgsql;
using System;
using VisionCloud.Domain.DtoModel.RabbitMq;
using VisionCloud.Utility.Security;
using VisionSurface.Web.Services;

namespace VisionSurface.Web.Extensions
{
    public static class StartupExtensions
    {
        /// <summary>
        /// 加载配置
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="env"></param>
        /// <returns></returns>
        public static IConfiguration CustomConfiguration(this IConfiguration configuration, IWebHostEnvironment env)
        {
            if (configuration == null)
                throw new ArgumentNullException(nameof(configuration));

            if (env == null)
                throw new ArgumentNullException(nameof(env));

            var builder = new ConfigurationBuilder();
            builder.SetBasePath(env.ContentRootPath)
                 .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true)
                 .AddJsonFile("ExternalAuth.json", true, true)
                 .AddEnvironmentVariables();

            configuration = builder.Build();
            Console.WriteLine($"当前环境Environment：{env.EnvironmentName}");

            return configuration;
        }

        /// <summary>
        /// 添加跨域请求
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddCustomCors(this IServiceCollection services)
        {
            services.AddCors(options =>
            {
                options.AddPolicy("cors", builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
            });

            return services;
        }

        /// <summary>
        /// 初始化pgsql数据库连接
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static IServiceCollection InitPgsqlConnection(this IServiceCollection services, IConfiguration configuration)
        {
            //注入Sql连接配置
            services.Configure<PgsqlSettingOptions>(configuration.GetSection("PgsqlSetting"));

            var options = configuration.GetSection("PgsqlSetting").Get<PgsqlSettingOptions>();
            if (string.IsNullOrWhiteSpace(options?.ConnectionMaster))
                throw new ArgumentNullException("ConnectionMaster is empty");

            options.ConnectionMaster = AesCoreHelper.Decrypt(options.ConnectionMaster, AesCoreHelper.Sceret);

            //初始化数据库连接
            PgSqlHelper.InitConnection(options);

            return services;
        }

        /// <summary>
        /// 注入rabbitmq订阅者服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="cfg"></param>
        /// <returns></returns>
        public static IServiceCollection AddRabbitMQConsumerService(this IServiceCollection services, IConfiguration cfg)
        {
            services.AddSingleton<IConsumerSubscriber, PushWxMessageService>();
            services.AddBlmRabbitMQConsumerUsePostgreSQL(options =>
            {
                var pgsql = cfg["PgsqlSetting:ConnectionMaster"];
                if (string.IsNullOrWhiteSpace(pgsql))
                    throw new ArgumentNullException("数据库连接不能为空");
                var rabbitmqOption = cfg.GetSection("RabbitMQOptions").Get<RabbitMQOption>();
                if (rabbitmqOption == null)
                    throw new ArgumentNullException(nameof(rabbitmqOption));

                options.Connection = () => new NpgsqlConnection(pgsql);
                options.Parameter = (key, value) => new NpgsqlParameter(key, value);
                options.StorageOptions.Retries = 3;
                options.StorageOptions.RabbitMQOptions.TryAddHost(new HostInfoModel
                {
                    Host = rabbitmqOption.HostName,
                    Port = rabbitmqOption.Port,
                    Username = rabbitmqOption.UserName,
                    Password = rabbitmqOption.Password,
                    EnableSSL = rabbitmqOption.EnableSSL,
                    ServerName = rabbitmqOption.ServerName,
                    CertPath = rabbitmqOption.CertPath,
                    CertPassphrase = rabbitmqOption.CertPassphrase,
                    Version = rabbitmqOption.Version
                }, rabbitmqOption.VirtualHost, RabbitMQConnectPoolName.CloudServerHost);
            });
            return services;
        }
    }
}
